package testjeu;

import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Date;
import java.util.Locale;

import org.newdawn.slick.AngelCodeFont;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;
import org.newdawn.slick.particles.ParticleIO;
import org.newdawn.slick.particles.ParticleSystem;


/**
 *  # 2ème state # Classe principale gérant le déroulement du jeu autours de 3 fonctions principales : init, update, render.
 *  <br />Gère aussi les actions clavier et souris
 * 
 * @author YoTsumi
 */
public class Jeu extends BasicGameState implements Constantes {
                
        int    FPS = 100;
        
        /** La fenêtre du jeu */
        private GameContainer container;
        
        /** Le background de l'interface, et la grille transparente */
        private Image bg, grille, explicationsInGame, finMission, astuceFinMission;
        
        /** La police Visitor 10px */
        private AngelCodeFont fontVisitor;
        
        /** Gestionnaire de messages */
        private Messages messages;
        private AngelCodeFont fontVerdana;
        
        /** Le tank dirigé par le joueur */
        private tank monTank;
        
        /** La map dans laquelle se dirige le joueur */
        private map lamap;
        
        /** Le gestionnaire de balles */
        private Balles balles;
        
        /** Les cartes d'actions possédées par le joueur pour finir le tableau */
        private Carte[] lesCartes;
        
        /** Var temporaire pour le parcours des cartes d'actions définis par la map */
        private Hashtable<Actions,Integer> listeCartesTemp=new Hashtable<Actions,Integer>();

        /** Les tanks ennemis */
        private ArrayList<TankEnnemi> lesTankEnnemis = new ArrayList<TankEnnemi>();
        private ArrayList<Mine> lesMinesEnnemis = new ArrayList<Mine>();
        
        /** Booléen indiquant si la carte doit être affichée ou non */
        private boolean afficher_grille=false;
        
        /** Booléen indiquant si une carte d'action est en cours de déplacement */
        private boolean uneCarteEnDéplacement=false;
        
        /** La carte en cours de déplacement */
        private Carte carteEnDéplacement;
        
        /** Booléen indiquant si la phrase de préparation est active ou non ( = phase de jeu passif ) */
        private boolean phasePréparation=true;
        
        /** Le state du jeu */
        private StateBasedGame game;
        
        /** TimeStamp au début et à la fin de la map **/
        private long tempsDebut, tempsFin;
        private int ms=0;
        
        /** Nombre d'essais pour la carte en cours */
        private int nbEssais;
        
        /** Score depuis le début et score de la map **/
        private int scoreTotal, scoreMap;
        
        /** Les explications ingame doivent-elles être affichées ? */
        private boolean afficher_explication=true;
        
        /** Fin de la mission ? Map suivante chargée **/
        private boolean mission_terminée=false;
        private boolean map_chargée=false;
        
        /** Le numéro du niveau en cours */
        private int num_level=-1;
        
        
        private ParticleSystem explosion;
        
        private ArrayList<Explosion> liste_explosions = new ArrayList<Explosion>();
        
        public static String log="<h2>Log du jeu: "+DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG,Locale.FRANCE).format(new Date())+"</h2>";
        
        /**
         * Retourne l'ID du state en cours
         * @return Id du state
         */
        public int getID()
        {
            return ID_jeu;
        } 

        /**
         * Initialise les éléments du jeu, ouvre la première map et débute une partie.
         * 
         * @param container     La fenêtre principale du jeu
         * @param arg1          State
         * @param arg1          State
         * @throws org.newdawn.slick.SlickException
         * @see #nouvellePartie()
         * @see #nouvelleMap(java.lang.String)
         */
        public void init(GameContainer container, StateBasedGame arg1) throws SlickException {
        	this.container = container;
            container.setTargetFrameRate(FPS);
            container.setShowFPS(false);
            
            bg = new Image("res/interface.png");
            grille = new Image("res/grille.png");
            explicationsInGame = new Image("res/explication_ingame.png");
            finMission = new Image("res/fin_mission.png");
            astuceFinMission = new Image("res/astuce_code.png");
            
            nouvelleMap(FIRST_MAP); // Antibug ^^
            nouvellePartie();
            
            messages=new Messages(190);
            fontVisitor=new AngelCodeFont("res/font/visitor10.fnt", "res/font/visitor10_00.tga");
            fontVerdana=new AngelCodeFont("res/font/verdana32.fnt", "res/font/verdana32_00.tga");
            
            this.game=arg1;
              
    		try {
    			explosion = ParticleIO.loadConfiguredSystem("res/feu.xml");
    		} catch (IOException e) {
    			throw new SlickException("Failed to load particle systems", e);
    		}
        }

        /**
         * Charge la map : soit la première soit celle trouvée via le code, lorsque l'on rentre dans cet état
         * 
         * @param container     Fenêtre du jeu
         * @param g             L'état du jeu
         * @throws org.newdawn.slick.SlickException
         */
        @Override
        public void enter(GameContainer container, StateBasedGame g) throws SlickException {          
              if (Menu.mapValide) {
                  nouvelleMap(Menu.map);
                  nouvellePartie();
                  afficher_explication=false;
              }
              
        }
                

        /**
         * Dessine les différents objets à l'écran
         * 
         * @param container     La fenêtre du jeu
         * @param arg1          State
         * @param g             L'objet graphique
         * @throws org.newdawn.slick.SlickException
         */
        public void render(GameContainer container, StateBasedGame arg1, Graphics g) throws SlickException {
		
        	// Dessine en fond la map
            lamap.dessiner();

            // Dessine les mines
            for (Mine m : lesMinesEnnemis)    m.dessiner(g);
            
             // Dessine les tank ennemis, leur vue et leur rayon laser
            for (TankEnnemi t:lesTankEnnemis) t.dessiner(g);
            
            // L'interface
            bg.draw();
            if (afficher_grille) grille.draw(280, 57);
            
            // Dessine les cartes
            for (Carte c: lesCartes) c.dessiner(g);
            Carte.réinit();
           
            // Infos de l'interface
            afficheTexte(g, "ComSat 2008 by YoTsumi", 16);
            fontVisitor.drawString(88, 27,lamap.map_nom() );
            fontVisitor.drawString(168, 27,lamap.map_auteur() );
            fontVisitor.drawString(250, 27,lamap.map_code() );
            fontVisitor.drawString(605,27, ""+(num_level+1));
            fontVisitor.drawString(755,27, ""+scoreTotal);
            fontVisitor.drawString(685,27, (ms/1000)+" s");
            
            // Des messages du gestionnaire
            messages.dessiner(g);
  
            // Le tank, les balles & enfin le feu
            if (!mission_terminée) {
            	monTank.dessiner();
                balles.dessiner();                
                for (Explosion e:liste_explosions) e.dessiner();
            }
            
            // Explication en image de la première map :
            if (afficher_explication) explicationsInGame.draw(185,69);
            
            // Message de fin de mission
            if (mission_terminée) {
            	finMission.draw(280,57);
            	afficheTexte(g, Integer.toString(scoreTotal), 538,418);
            	afficheTexte(g, lamap.map_code(), 538, 477);
            	if (num_level==1) astuceFinMission.draw(280+45, 57+447);
            }
                 
	}

        
        
        /**
         * Affiche un message centré à l'écran en blanc avec une ombre noire
         * 
         * @param g     Le contexte graphique
         * @param msg   Le message à afficher
         * @param y     la coordonnée y à laquelle placer le texte
         */
        private void afficheTexte(Graphics g, String msg, int y) {
			g.setColor(Color.black);
			g.drawString(msg, 450-(g.getFont().getWidth(msg)/2), y+1);
			g.setColor(Color.white);
			g.drawString(msg, 450-(g.getFont().getWidth(msg)/2), y);
        }

        /**
         * Affiche un message à l'écran en blanc avec une ombre noire
         * 
         * @param g     Le contexte graphique
         * @param msg   Le message à afficher
         * @param x		Coordonnée x du message
         * @param y     Coordonnée y du message
         */
        private void afficheTexte(Graphics g, String msg, int x, int y) {
			g.setColor(Color.black);
			fontVerdana.drawString(x, y+1, msg);
			g.setColor(Color.white);
			fontVerdana.drawString(x, y, msg);
        }
        
        

        /**
         * Met à jour les différents éléments du jeu, et gère les actions des différentes cases actions
         * 
         * @param containerr        La fenêtre du jeu
         * @param arg1              State
         * @param delta             Le temps écoulé depuis la dernière update
         * @throws org.newdawn.slick.SlickException
         */
        public void update(GameContainer containerr, StateBasedGame arg1, int delta) throws SlickException {	
        	
        	ArrayList<Explosion> Explosions_a_suppr=new ArrayList<Explosion>();
        	for (Explosion e:liste_explosions) {
        		if (!e.update(delta)) Explosions_a_suppr.add(e);
        	}
        	liste_explosions.removeAll(Explosions_a_suppr);
        	
        	if (mission_terminée && !map_chargée)  {
        		nouvelleMap(lamap.map_suivante());
        		map_chargée=true;
        	}
        	
            messages.update(delta);
            
            // ########### UPDATE DES BALLES ########## //
            // Si l'update des balles retourne vrai, alors notre tank est touché par un tir adverse !
            if (balles.update(delta, monTank.tankCol(), monTank.tankLig()/*, monTank.tankAngle()*/)) {
            	monTank.explosion();

            	nouvelle_explosion(cases.colToPxl(monTank.tankCol())+20, cases.ligToPxl(monTank.tankLig())+20);
                
            	messages.ajouter("!!!!!!!!! Boummm !!!!", 250, 3);
                messages.ajouter("Vous venez de vous faire exploser !", 300, 4);
                messages.ajouter("Mission échouée", 400, 6);
            }
            
            // On parcours les ennemis détruits
            ArrayList<TankEnnemi> listeEnnemisDétruits;
            listeEnnemisDétruits=balles.liste_ennemis_détruits();
            
            for (TankEnnemi t:listeEnnemisDétruits) {
                   t.détruire();
                   lamap.adversaire_detruit(t.col(), t.lig());
                   
                   nouvelle_explosion(t.x()+20, t.y()+20);
            }
            
            // On parcours les mines détruites
            ArrayList<Mine> listeMinesDétruites;
            listeMinesDétruites=balles.liste_mines_détruitees();
            
            for (Mine m:listeMinesDétruites) {
                   m.détruire();
                   lamap.adversaire_detruit(m.col(), m.lig());
                   
                   nouvelle_explosion(m.x()+20, m.y()+20);
            }
            
            
            // Action dans laquelle arrive le tank
            Actions actionEnCours=lamap.action_Case(monTank.tankCol(), monTank.tankLig());
            
            if (monTank.estDansNouvelleCase()) {  // Nouvelle action détectée
                
                // Le tank est-il tjs sur la map ?
                if (monTank.tankCol()==-1 || monTank.tankLig()==-1) 
                    actionEnCours=Actions.Out;
                    
                // Le tank est-il a portée de tir ?
                boolean feu=false; 
                if ((monTank.tankCol()>0 && monTank.tankCol()<=15 && monTank.tankLig()>0 && monTank.tankLig()<=15) && !monTank.estInvincible()) {
                    int i=0;
                    
                    while (!feu && i<lesTankEnnemis.size()) {
                        
                    	// Notre tank est dans la ligne de mire d'un ennemi
                        if (((TankEnnemi)lesTankEnnemis.get(i)).estDansPortéeDeTir(monTank.tankCol(), monTank.tankLig(), monTank.tankLastCol(), monTank.tankLastLig(), monTank.tankAngle() )) {
                        	
                        	// Le tank ennemi tir !
                        	TankEnnemi tankTueur=lesTankEnnemis.get(i);
                        	balles.ajouter(tankTueur.col(), tankTueur.lig(), tankTueur.angle(), true);
                        	
                        	// Si cas compliqué de diag, on fait exploser le tank direct
                        	if (monTank.tankAngle()%90!=0 && tankTueur.angle()%90!=0 && monTank.tankAngle()-tankTueur.angle()%90==0) {
                            	monTank.explosion();

                                nouvelle_explosion(cases.colToPxl(monTank.tankCol())+20, cases.ligToPxl(monTank.tankLig())+20);

                                messages.ajouter("!!!!!!!!! Boummm !!!!", 250, 3);
                                messages.ajouter("Vous venez de vous faire exploser !", 300, 4);
                                messages.ajouter("Mission échouée", 400, 6);
                        	}
                        	monTank.setEtat(Etat.Repos);
                            feu=true;
                        } else i++;
                    
                    }
                    
                }
                
                // Si le tank n'a pas été tuée : nouvelle case = nouvelle action
                if (!feu)
                {
                    switch (actionEnCours) {
                        case Bloqué:
                        case Ennemi:
                        case Mine:
                            monTank.setEtat(Etat.Détruit);
                            messages.ajouter("Boing !!!!", 250, 3);
                            messages.ajouter("Vous venez de heurter un obstacle !", 300, 4);
                            messages.ajouter("Mission échouée", 400, 6);
                            
                            nouvelle_explosion(cases.colToPxl(monTank.tankCol())+20, cases.ligToPxl(monTank.tankLig())+20);
                            
                        break;

                        case Plouf:
                            monTank.setEtat(Etat.Détruit);
                            messages.ajouter("Plouf !!!!", 250, 3);
                            messages.ajouter("Vous venez de tomber à l'eau !", 300, 4);
                            messages.ajouter("Mission échouée", 400, 6);
                            
                            nouvelle_explosion(cases.colToPxl(monTank.tankCol())+20, cases.ligToPxl(monTank.tankLig())+20);
                            
                        break;
                        
                        case Out:
                            monTank.setEtat(Etat.Détruit);
                            messages.ajouter("Héééhoooo !!!!", 250, 3);
                            messages.ajouter("La désertion n'est pas autorisée soldat !", 300, 4);
                            messages.ajouter("Mission échouée", 400, 6);
                            
                            nouvelle_explosion(cases.colToPxl(monTank.tankCol())+20, cases.ligToPxl(monTank.tankLig())+20);
                            
                        break;
                        
                        case Fin:
                            monTank.setEtat(Etat.AttenteOrdre);
                            mission_terminée=true;
                            
                            tempsFin = new Date().getTime();
                            int diffTps=(int)(tempsFin-tempsDebut)/1000;
                            
                            scoreMap=SCORE_BASE - diffTps*SCORE_COEFF_TEMPS - (nbEssais-1)*SCORE_COEFF_ESSAIS;
                            debug("Temps = "+diffTps+" & NbEssais = "+nbEssais);
                            scoreTotal+=scoreMap;

                            log+="Mission "+lamap.map_fichier()+" ("+num_level+") - Temps : "+diffTps+" - Essais : "+(nbEssais-1)+" - Score : "+scoreMap+"<br />";
                            
                        break;
                        
                        case DirectionH:
                            monTank.direction(270); 
                        break;

                        case DirectionG:
                            monTank.direction(180);
                        break;

                        case DirectionB:
                            monTank.direction(90);                         
                        break;

                        case DirectionD:
                            monTank.direction(0);
                        break;
                        
                        case DirectionDB:
                            monTank.direction(45); 
                        break;
                        
                        case DirectionBG:
                            monTank.direction(135);
                        break;
                                                
                        case DirectionGH:
                            monTank.direction(225);
                        break;
                                                
                        case DirectionHD:
                            monTank.direction(315);
                        break;
                        
                        // Tir et Tir 4 : actions spéciales : car on entre dans ce cas à chaque update, non à chaque nouvelle case
                        case Tir:
                            // Si le tank n'a pas encore tiré, on cré la balle
                            if ( !monTank.tirEnCours()) {
                                 monTank.tirer();
                                 balles.ajouter(monTank.tankCol(), monTank.tankLig(), monTank.tankAngle());
                            }
                        break;
                        
                        case Tir4:
                            // Si le tank n'a pas encore tiré, on cré la balle
                            if ( !monTank.tirEnCours()) {
                                 monTank.tirer();
                                 monTank.nouvelleCase();
                                 for (int i=0; i<4; i++)  balles.ajouter(monTank.tankCol(), monTank.tankLig(), (monTank.tankAngle()+i*90)%360);
                                 
                            }
                        break;
                        
                        case Bouclier:
                            monTank.invincible(3);

                        default :
                            monTank.avancer();
                        break;
                        
                    }
                }
            }
            
            else if (monTank.tirEnCours()) {
                
                // La balle est en cours de mouvement, on attend qu'elle disparaisse pour refaire partir le tank
                if (!balles.en_mouvement()) monTank.avancer(); 
           
            }
            
            ms+=delta;
           

	}


        public void nouvelle_explosion(int x, int y) throws SlickException {
            liste_explosions.add(new Explosion(x,y, explosion.duplicate()));
        }
        
        
        
        /**
         * Réinitialise la partie ( 'Annuler ordres' )
         * 
         * @throws org.newdawn.slick.SlickException
         */
        public void nouvellePartie() throws SlickException {
              
                lamap.reset();
                
                monTank=new tank(lamap.tank_depart_x(),lamap.tank_depart_y());
                monTank.setAngle(lamap.tank_depart_angle());
                monTank.setEtat(Etat.AttenteOrdre);
                
                afficher_grille=false;
                uneCarteEnDéplacement=false;
                phasePréparation=true;
                
                for (Carte c : lesCartes) c.reset();
                for (TankEnnemi t : lesTankEnnemis) t.reset();
                for (Mine m : lesMinesEnnemis) m.reset();
                liste_explosions.clear();
                
                balles=new Balles(lesTankEnnemis, lesMinesEnnemis, lamap);
                nbEssais++;
        }
        
        
        /**
         * Charge une nouvelle carte et met à jour les cartes actions
         * 
         * @param nomMap    Le nom de la map à charger qui se situe dans res/maps/  sans le préfixe 'map_' ni l'extension '.tmx'
         * @throws org.newdawn.slick.SlickException
         * @see #nouvellePartie()
         */
        public void nouvelleMap(String nomMap) throws SlickException {
                
    		if (nomMap.equals("")) 			game.enterState(ID_fin, new FadeOutTransition(), new FadeInTransition());
    		else if (map.existe(nomMap))    { lamap=new map(nomMap); }
    		else 							game.enterState(ID_erreur, new FadeOutTransition(), new FadeInTransition());
    			
            
            // On liste les cartes dispo
            listeCartesTemp=lamap.liste_cartes();
            Carte.relations();
            
            // On liste les tanks ennemis
            lesTankEnnemis.clear();
            lesTankEnnemis.addAll(lamap.liste_ennemis());
            
            // On liste les mines ennemies
            lesMinesEnnemis.clear();
            lesMinesEnnemis.addAll(lamap.liste_mines());
            
            // On compte les cartes ki sont réellements présentent
            int nbCartes=0;
            Enumeration<Actions> e = listeCartesTemp.keys();
            while (e.hasMoreElements()) {
                int nb=(Integer)listeCartesTemp.get((Actions)e.nextElement());
                if (nb>0) nbCartes++;
            }
                
           // On ajoute dans une matrice les cartes réelles         
            lesCartes=new Carte[nbCartes];
            e = listeCartesTemp.keys();
            int j=0;
            while (e.hasMoreElements()) {
                Actions c=(Actions)e.nextElement();
                int nb=(Integer)listeCartesTemp.get(c);
                if (nb>0) {
                    lesCartes[j]= new Carte(c, nb);
                    j++;
                }
            } 
            
            tempsDebut=new Date().getTime();
            nbEssais = 0;
            scoreMap=0;
            num_level++;
            ms=0;
        }
        
        /**
         * Actions lorsque les boutons de la sourie sont actionnés :
         *  - Clic sur le bouton 'Lancer les moteurs'
         *  - Clic sur le bouton 'Annuler ordres'
         *  - Clic sur une carte pendant la période de préparation en vue de la déplacer
         * 
         * @param button        Le numéro du bouton cliqué ( 0=clic gauche )
         * @param x             Coordonnée x du clic
         * @param y             Coordonnée y du clic
         */
        @Override
        public void mousePressed(int button, int x, int y) {
            
            if (button==0){ // Click gauche
                
            	if (!mission_terminée) {
            		
            	
	            	// Click sur 'Lancer moteurs'
	                if (x>=40 && y>=462 && x<=220 && y<=491) {
	                    /*try {
	                        messages.ajouter("Lancement des moteurs !", 200, 1);
	                    } catch (SlickException ex) {
	                        ex.printStackTrace();
	                    }*/
	                    if (!monTank.estDétruit()) {
	                        monTank.avancer();
	                        phasePréparation=false;
	                    }
	                    if (afficher_explication) afficher_explication=false;
	                }
	                
	                // Click sur 'Annuler ordres'
	                if (x>=40 && y>=504 && x<=220 && y<=532) {
	                    try {
	                        messages.supprimerTous();
	                        messages.ajouter("J'attends les ordres commandant !", 300, 1);
	                        nouvellePartie();
	                    } catch (SlickException ex) {
	                        ex.printStackTrace();
	                    }
	                    if (afficher_explication) afficher_explication=false;
	                }
	                
	                // Click sur une carte ??
	                if (phasePréparation) {
	                    for (Carte c: lesCartes) {
	                    	
	                        if (c.estPointéOrigine(x,y)) {
	                        	
	                            c.debutDéplacement();
	                            carteEnDéplacement=c;
	                            uneCarteEnDéplacement=true;
	                            afficher_grille=true;
	                            
	                            if (afficher_explication) afficher_explication=false;
	                            
	                        // Reprendre le déplacement
	                        } else if (c.estPointéSurCarte(x, y)!=-1) {
	                            c.reprendreDéplacement(c.estPointéSurCarte(x, y));
	                            lamap.ajouter_action(cases.pxlToCol(x), cases.pxlToLig(y), Actions.Rien);
	                            
	                            carteEnDéplacement=c;
	                            uneCarteEnDéplacement=true;
	                            afficher_grille=true;
	                        }
	                    }
	                }
	                
            	}
            	
            	
                // Fin de la mission et click sur 'Mission suivante'
                if (mission_terminée && x>=466 && x<=466+220 && y>=312 && y<=312+43) {
                	
                	try {
						nouvellePartie();
						mission_terminée=false;
						map_chargée=false;
					} catch (SlickException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
                	
                }
            }
	}
        
        /**
         * Lorsque qu'un bouton de la souris est relaché :
         *  - Fin de déplacement d'une carte action
         * 
         * @param button
         * @param x
         * @param y
         */
        @Override
        public void mouseReleased(int button, int x, int y) {
            if (uneCarteEnDéplacement) {     
                uneCarteEnDéplacement=false;
                if ( carteEnDéplacement.placer(x, y, lamap.action_Case(cases.pxlToCol(x), cases.pxlToLig(y))) ) 
                    lamap.ajouter_action(cases.pxlToCol(x), cases.pxlToLig(y), carteEnDéplacement.get_action());
                afficher_grille=false;
            }
        }
 
        /**
         * Lorsque la souris est déplacé : 
         *  - Si une carte est en déplacement, on la bouge aux nouvelles coordonnées et on vérifie si le déplacement est autorisé
         * 
         * @param oldx  Ancienne coordonnée x
         * @param oldy  Ancienne coordonnée y
         * @param newx  Nouvelle coordonnée x
         * @param newy  Nouvelle coordonnée y
         */
        @Override
        public void mouseMoved(int oldx, int oldy, int newx, int newy) {
            // Si il y a une carte en déplacement, on la bouge
            if (uneCarteEnDéplacement) {
                carteEnDéplacement.déplacer(newx, newy, lamap.action_Case(cases.pxlToCol(newx), cases.pxlToLig(newy)));
            }
            
            // Si on pointe une carte déjà placée, on la met en surbrillance :
            for (Carte c : lesCartes) {
                if (c.estPointéSurCarte(newx, newy)!=-1) 
                    c.surligner(true, c.estPointéSurCarte(newx, newy));
                
                else if (c.estPointéOrigine(newx, newy)) 
                    c.surligner(true,0); 
                            
                else c.surligner(false);
            }
        }
        
        
        /**
         * Lorsque une touche du clavier est pressée :
         *  - ESPACE = On affiche la grille
         *  - F12 = On affiche les fps
         * 
         * @param key   Le code de la touche appuyé
         * @param c     ?
         */
        @Override
        public void keyPressed(int key, char c) {
            
            switch(key) {
                case Input.KEY_SPACE:
                    afficher_grille=true;
                break;
                case Input.KEY_F12:
                    container.setShowFPS(!container.isShowingFPS());
                break;
                case Input.KEY_F3:
                    FPS=5;
                break;
                case Input.KEY_F4:
                    FPS=25;
                break;
                case Input.KEY_F5:
                    FPS=50;
                break;
                case Input.KEY_F6:
                    FPS=100;
                break;
                case Input.KEY_F7:
                    FPS=200;
                break;
                case Input.KEY_F8:
                    FPS=300;
                break; 
            }
            if (key == Input.KEY_ESCAPE) {
            	game.enterState(ID_menu, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
            }

            //container.setTargetFrameRate(FPS);
        }

        
        /**
         * Lorsque une touche du clavier est relachée :
         *  - ESPACE : On cache la grille
         * 
         * @param key
         * @param c
         */
        @Override
        public void keyReleased(int key, char c) {
            
            switch(key) {
                case Input.KEY_SPACE:
                    afficher_grille=false;
                break;
            }
        }
     
        
        
        public static void debug(String mess) {
            //if(DEBUG) System.out.println(mess);
        }
}


